'use strict'
/**
 * AxiosUtil
 * axios请求工具类
 * 你是一段成熟的代码，要学会自己改bug  ----我是小尾巴
 */
import token from "../../../utils/js/config/token"
import {requestPost} from "../../../utils/js/HttpUtil"
// 引入axios
import axios from 'axios'
// 引入message消息提示
import messageUtil from '../MessageUtil'
// 引入mask遮罩层
import {openMask, closeMask} from '../MaskUtil'
// 使用iView插件，显示加载条
import iView from 'iview'
// 使用路由
import router from '../../../router/index'

// 引入xhr参数信息
import {responseType, requestMethod, httpParams} from '../config/http.config.js'
import {page} from '../config/page.config.js'

const defaultParam = {
  /**
   * 默认几种请求方法的前缀
   */
  METHOD_PREFIX: 'request',
  /**
   * 请求时的处理方法
   */
  DEFAULT_REQUEST: {
    /**
     * 遮罩层参数
     */
    mask: {
      close: true
    },
    /**
     * 异常处理函数
     */
    error: null
  }
}

/**
 * 创建axios对象实例
 * @type {AxiosInstance}
 */
const instance = axios.create({
  // `baseURL` 将自动加在 `url` 前面，除非 `url` 是一个绝对 URL。
  baseURL: httpParams.PREFIX,
  // `withCredentials` 表示跨域请求时是否需要使用凭证
  withCredentials: true
})

const defaultMethod = {
  /**
   * 获取axios对象
   * @param url
   * @param params
   * @param data
   * @param method
   * @param responseType
   * @param config
   * @returns {AxiosPromise}
   */
  getAxiosObject ({url = '', params = {}, data = {}, method = requestMethod.GET, resType = responseType.JSON, config = {}}) {
    const object = {
      ...config,
      method,
      url,
      headers: httpParams.HEADER,
      withCredentials: true,
      responseType: resType
    }
    // 如果是POST请求，post请求要用formData传值
    if (method.toLowerCase() === requestMethod.POST) {
      let formData = new FormData()
      Object.entries(params).forEach(([key, value]) => {
        formData.append(key, value)
      })
      object['data'] = formData
    } else {
      object['params'] = params
    }
    return instance(object)
  },
  /**
   * xhr请求
   * @param url
   * @param params
   * @param success
   * @param data
   * @param method
   * @param responseType
   * @param mask
   */
  xhr ({url = '', params = {}, success = null, data = {}, method = requestMethod.GET, resType = responseType.JSON, other = defaultParam.DEFAULT_REQUEST}) {
    const object = this.getAxiosObject({url, params, data, method, resType, config: other.config})
    this.baseXhr({
      axiosList: [object],
      success,
      other
    })
  },
  /**
   * 并发请求（多个请求，注意自己处理异常信息）
   * @param axiosList
   * @param success
   * @param other 默认为一个空对象
   */
  baseXhr ({axiosList = [], success = null, other = defaultParam.DEFAULT_REQUEST}) {
    iView.LoadingBar.start()
    // 打开遮罩层
    if (other.mask) {
      openMask()
    }
    if (!(axiosList instanceof Array) || axiosList.length === 0) {
      // console.log('请求异常')
      return
    }
    // 全部为并行请求，统一处理
    axios.all(axiosList).then(axios.spread((...response) => {
      const resArray = response.map(res => res.data)
      let errorCount = 0
      let hasNoLogin = false
      resArray.forEach(item => {
        if (item.code < 0) {
          errorCount++
          closeMask()
          messageUtil.notice.error(item.message)
          //为新增处理，一旦出现新增失败，后台会清调token，此处重新请求并赋值token
          requestPost("/system/safe/getReSubmitToken", {}, (data) => {
            token.token=data.data
          })
        }
        hasNoLogin = hasNoLogin || item.code === 9
      })
      if (hasNoLogin) {
        // 未登录
        router.push(page.LOGIN)
      }
      if (errorCount < resArray.length) {
        success(...resArray)
        iView.LoadingBar.finish()
      } else {
        iView.LoadingBar.error()
      }
    })).catch(error => {
      // 请求错误，强行关闭遮罩层
      if (other.mask) {
        closeMask()
      }
      iView.LoadingBar.error()
      // 如果有自定义的异常处理方法
      if (other.error) {
        other.error(error)
      } else {
        // 异常信息
        if (error.response) {
          messageUtil.notice.error(error.response.data.message)
        }
      }
    }).finally(() => {
      // 关闭遮罩层
      if (other.mask && other.mask.close) {
        closeMask()
      }
    })
  },
  /**
   * 初始化
   */
  init () {
    // 初始化四种封装的请求方法 Get Post Delete Put
    // 遍历requestMethod对象进行新建方法
    Object.keys(requestMethod).forEach(m => {
      let methodName = m.toLowerCase()
      if (defaultParam.METHOD_PREFIX) {
        let tempArray = methodName.split('')
        tempArray[0] = tempArray[0].toUpperCase()
        methodName = defaultParam.METHOD_PREFIX + tempArray.join('')
      }
      exportMethod[methodName] = ({method = m, url, data, params, success, resType = responseType.JSON, other}) => {
        defaultMethod.xhr({method, url, data, params, success, resType, other})
      }
    })
  }
}

const exportMethod = {
  /**
   * 获取参数
   * @returns {{responseType: {BLOB: string, NULL: string, JSON: string, TEXT: string}, httpParams: {PREFIX: string, PACKAGE: string, BASE_URL: string}, requestMethod: {DELETE: string, POST: string, GET: string, PUT: string}}}
   */
  getParam () {
    return {httpParams, responseType, requestMethod}
  },
  /**
   * 获取ajax请求对象
   * @param method
   * @param url
   * @param params
   * @param resType
   * @returns {*}
   */
  requestObject (method, url, params, resType) {
    return defaultMethod.getAxiosObject({url, params, method, resType})
  },
  /**
   * 并发请求处理
   * @param axiosList
   * @param success
   * @param other
   */
  requestAll (axiosList, success, other) {
    defaultMethod.baseXhr({axiosList, success, other})
  },
  /**
   * ajax请求
   * @param method
   * @param url
   * @param params
   * @param success
   * @param resType
   * @param other
   */
  request (method, url, params, success, resType, other) {
    defaultMethod.xhr({method, url, params, success, resType, other})
  }
}

// 初始化对象中的方法
defaultMethod.init()

// 导出
export default exportMethod
